from odoo import fields, models, api, _
from odoo.exceptions import UserError
from odoo.exceptions import ValidationError


class CRMLead(models.Model):
    _inherit = 'crm.lead'

    name = fields.Char(copy=False, default='Offer')
    partner_id = fields.Many2one(domain=[('is_company', '=', True), ('code', '!=', False), ('supplier_rank', '<=', 0)])
    contact = fields.Many2one('res.partner', string="Contact", domain="[('parent_id', '=', partner_id), ('type', '=', 'contact')]")
    delivery = fields.Many2one('res.partner', string="Delivery Address", domain="[('parent_id', '=', partner_id),('type', '=', 'delivery')]")
    layer = fields.Integer(string="Layer", default=1, group_operator='avg')
    board_thk = fields.Float(string="Board Thk.(mm)", default=1.0)
    internal_copper_thk = fields.Integer(string="Int Copper Thk(um)", default=1)
    external_copper_thk = fields.Integer(string="Ext Copper Thk(um)", default=1)
    surface_finish = fields.Char(string="Surface Finish")
    unit_size_long = fields.Float(string="Unit Size(L/mm)", default=1.0)
    unit_size_width = fields.Float(string="Unit Size(W/mm)", default=1.0)
    panel_size_long = fields.Float(string="Panel Size(L/mm)", default=1.0)
    panel_size_width = fields.Float(string="Panel Size(W/mm)", default=1.0)
    pcs_in_panel = fields.Integer(string="Pcs/Panel", default=1)
    unit_price = fields.Float(string="Unit Price", default=1.0)
    materials_cost = fields.Monetary(string="Materials Cost(CNY)", default=1.0, currency_field='currency_cny')
    production_cost = fields.Float(string="Production Cost", default=1.0)
    customer_price = fields.Float(string="Customer Price", default=1.0)
    remarks = fields.Text(string="Remarks")
    external_remarks = fields.Html(string="External Remarks")
    quotation_lines = fields.One2many('crm.quotation.line', 'crm_id', string="Quotation Lines", copy=True)
    commission = fields.Float(string="Commission", compute="_compute_commission", store=True)
    remark_html = fields.Html(string="Remark")
    official = fields.Boolean(string="Official", default=True)
    # incoterm = fields.Many2one('res.partner.incoterm', string="Incoterm", compute="_compute_co_incoterm", store=True)
    incoterm_id = fields.Many2one('account.incoterms', string="Incoterm", related="delivery.incoterm")
    board_material = fields.Char(string="Board Material")
    surface_treatment = fields.Char(string="Surface Treatment")
    rev = fields.Char(string="REV")
    customer_currency = fields.Many2one("res.currency", string="Currency", related="partner_id.currency_id", store=True)
    company_currency = fields.Many2one(compute="_sb_compute_company_currency")
    quotation_number = fields.Char(string="Quotation Number", default='Offer')
    cost_of_surface = fields.Monetary(string="Surface Cost(CNY)", default=0.0, currency_field='currency_cny')
    other_expenses_i = fields.Monetary(string="Other Cost 1(CNY)", default=0.0, currency_field='currency_cny')
    other_expenses_ii = fields.Float(string="Other Cost 2(%)", default=0.0)
    utilization_rate = fields.Float(string="Utilization Rate", default=0.0)
    end_customer = fields.Char(string="End Customer")
    project_name = fields.Char(string="Project Name")
    currency_cny = fields.Many2one('res.currency', string="Currency", default=lambda self: self.env.ref('base.CNY').id)
    currency_usd = fields.Many2one('res.currency', string="Currency", default=lambda self: self.env.ref('base.USD').id)
    usd_to_cny_rate = fields.Float(string="USD to CNY", compute="_compute_usd_to_cny_rate")
    usd_to_thb_rate = fields.Float(string="USD to THB", compute="_compute_usd_to_thb_rate")
    eau = fields.Integer(string="EAU")
    tooling_cost = fields.Boolean(string="Tooling Cost", default=False)
    material_lt = fields.Boolean(string="Material LT", default=False)
    ttl_freight = fields.Boolean(string="Total Freight", default=False)
    target = fields.Boolean(string="Target Price", default=False)
    nre_bool = fields.Boolean(string="NRE", default=True)
    mov_bool = fields.Boolean(string="MOV", default=True)
    expected_revenue = fields.Monetary(string="Expected Revenue", compute="_compute_expected_revenue", store=True)
    s_simi_fg = fields.Boolean(string='Semi-FG', default=False)
    # _sql_constraints = [
    #     ('name_customer_unique', 'UNIQUE(name, partner_id)', 'The combination of PN and Customer must be unique!!'),
    # ]
    _sql_constraints = [
        #  Offer 允许重名
        ('offer_can_dup',
         'UNIQUE (name) WHERE name = \'Offer\'',
         'Offer type can be duplicated.'),

        #  非 Offer 必须 (name + partner_id) 唯一
        ('name_partner_unique',
         'UNIQUE (name, partner_id) WHERE name != \'Offer\'',
         'The combination of PN and Customer must be unique!'),
    ]

    @api.model
    def create(self, vals):
        # 排除特殊名稱
        if vals.get('name') != 'Offer':
            dup = self.search([
                ('name', '=', vals.get('name')),
                ('partner_id', '=', vals.get('partner_id')),
            ])
            if dup:
                raise ValidationError('The combination of Name, Customer must be unique!!')

        # 把聯絡人上的 salesperson 帶過來
        if vals.get('partner_id'):
            partner = self.env['res.partner'].browse(vals['partner_id'])
            vals.setdefault('user_id', partner.user_id.id)

        return super(CRMLead, self).create(vals)

    def write(self, vals):
        for rec in self:
            if rec.quotation_number == 'Offer':
                vals = dict(vals)
                vals['quotation_number'] = self.env['ir.sequence'].next_by_code('crm.qn.sequence')

            if 'name' in vals and vals['name'] != 'Offer':
                existing = self.search([
                    ('id', '!=', rec.id),  # 排除自己
                    ('name', '=', vals['name']),
                    ('partner_id', '=', rec.partner_id.id),
                ])
                if existing:
                    raise ValidationError(
                        'The combination of Name and Customer must be unique!'
                    )

        return super(CRMLead, self).write(vals)

    def copy(self, default=None):
        if default is None:
            default = {}
        default['name'] = 'Offer'  # 设置默认值
        return super(CRMLead, self).copy(default)

    @api.onchange('create_date')
    def _compute_usd_to_cny_rate(self):
        # 获取美元和人民币的汇率
        usd_currency = self.env.ref('base.USD')  # 获取美元货币记录
        cny_currency = self.env.ref('base.CNY')  # 获取人民币货币记录

        if usd_currency and cny_currency:
            # 使用订单的创建日期作为查询汇率的日期
            create_date = self.create_date
            # usd_to_cny = usd_currency.with_context(date=create_date).rate / cny_currency.with_context(date=create_date).rate
            rate = self.env['res.currency']._get_conversion_rate(usd_currency, cny_currency, date=create_date)
            self.usd_to_cny_rate = rate

    @api.onchange('create_date')
    def _compute_usd_to_thb_rate(self):
        # 获取美元和泰铢的汇率
        usd_currency = self.env.ref('base.USD')  # 获取美元货币记录
        thb_currency = self.env.ref('base.THB')  # 获取泰铢货币记录

        if usd_currency and thb_currency:
            # 使用订单的创建日期作为查询汇率的日期
            create_date = self.create_date
            # usd_to_thb = usd_currency.with_context(date=create_date).rate / thb_currency.with_context(date=create_date).rate
            rate = self.env['res.currency']._get_conversion_rate(usd_currency, thb_currency, date=create_date)
            self.usd_to_thb_rate = rate

    @api.depends('partner_id')
    def _sb_compute_company_currency(self):
        for rec in self:
            if rec.partner_id:
                rec.company_currency = rec.partner_id.currency_id.id
            else:
                rec.company_currency = self.env.company.currency_id.id

    @api.depends('partner_id', 'partner_id.property_product_pricelist')
    def _compute_customer_currency(self):
        for re in self:
            re.customer_currency = re.partner_id.property_product_pricelist.currency_id.id

    @api.onchange('partner_id')
    def _compute_incoterm(self):
        if self.partner_id.shipping_child_ids:
            self.delivery = self.partner_id.shipping_child_ids[0].id
        else:
            self.contact = False

    @api.depends('delivery')
    def _compute_co_incoterm(self):
        for rec in self:
            if rec.delivery:
                # rec.incoterm = rec.delivery.incoterm_id.id
                rec.incoterm_id = rec.delivery.incoterm.id
            else:
                rec.incoterm_id = False

    @api.depends('partner_id')
    def _compute_commission(self):
        for rec in self:
            if rec.partner_id.financial_contact_line_ids:
                rec.commission = rec.partner_id.financial_contact_line_ids[0].commission
            else:
                rec.commission = 0.0

    def _check_similar_quote(self, vals):
        # 获取当前要保存的报价的相关字段值
        unit_size_width = vals.get('unit_size_width', self.unit_size_width)
        unit_size_long = vals.get('unit_size_long', self.unit_size_long)
        layer = vals.get('layer', self.layer)

        # 判断字段是否都已填写
        if unit_size_width and unit_size_long and layer:
            # 查找是否已经存在相同的报价（排除当前记录）
            existing_quotes = self.search([
                ('unit_size_width', '=', unit_size_width),
                ('unit_size_long', '=', unit_size_long),
                ('layer', '=', layer),
                ('id', '!=', self.id)  # 排除当前记录
            ])

            if existing_quotes:
                # 如果找到相似报价，弹出提示
                similar_quote = existing_quotes[0]  # 获取第一个找到的报价
                raise UserError(
                    f"Similar to the quote number {similar_quote.quotation_number}, please record the requirements."
                )

    @api.depends('eau', 'quotation_lines.unit_price', 'quotation_lines.qty')
    @api.onchange('eau', 'quotation_lines.unit_price', 'quotation_lines.qty')
    def _compute_expected_revenue(self):
        for rec in self:
            if rec.eau and rec.quotation_lines:
                # 对 quotation_lines 按照 qty 升序排序
                sorted_lines = sorted(rec.quotation_lines, key=lambda line: line.unit_price)
                # 取排序后的第一个记录的 unit_price
                first_line = sorted_lines[0] if sorted_lines else None
                rec.expected_revenue = first_line.unit_price * rec.eau if first_line else 0
            else:
                rec.expected_revenue = 0

    def download_excel(self):
        # 返回下载模板链接
        return {
            'type': 'ir.actions.act_url',
            'url': f"/web/content/?model=ir.attachment&id={self.env.ref('sb_crm_ext.crm_lead_template_attachment').id}&filename_field=datas_fname&field=datas&download=true&filename=crm_lead_template.xlsx",
            'target': 'self',
        }
